package apis

import (
	"fmt"
	"log"
	"mime/multipart"
	"net/http"
	"os"
	"path"
	"path/filepath"
	"strings"
	"tads/server/app/business/service"
	"tads/server/app/business/service/dto"
	"tads/server/core/sdk/api"
	"time"

	"github.com/gin-gonic/gin"
	"github.com/gin-gonic/gin/binding"
)

type Icon struct {
	api.Api
	IconPath       string
	IconAttackPath string
}

const images_dir = "./uploads"

func (i Icon) Get(c *gin.Context) {
	req := dto.IconGetRequests{}
	s := service.Icon{}
	err := i.MakeContext(c).MakePostgres().Bind(&req, binding.Query).MakeService(&s.Service).Errors
	if err != nil {
		i.Logger.Errorf("请求参数错误: %s!\n", err.Error())
		c.JSON(http.StatusOK, gin.H{"code": 400, "msg": fmt.Sprintf("请求参数错误: %s!\n", err.Error())})
		return
	}
	response, err := s.Get(&req)
	if err != nil {
		i.Logger.Errorf("组件获取错误：%s\n", err.Error())
		c.JSON(http.StatusOK, gin.H{"code": 400, "msg": fmt.Sprintf("组件获取错误：%s\n", err.Error())})
		return
	}
	i.Logger.Info("组件获取成功")
	c.JSON(http.StatusOK, gin.H{"code": 200, "msg": "组件获取成功", "data": response})
	return
}

func (i Icon) Inset(c *gin.Context) {
	req := dto.IconInsetRequests{}
	s := service.Icon{}
	err := i.MakeContext(c).MakePostgres().Bind(&req, binding.Form).MakeService(&s.Service).Errors
	if err != nil {
		i.Logger.Errorf("请求参数错误: %s!\n", err.Error())
		c.JSON(http.StatusOK, gin.H{"code": 400, "msg": fmt.Sprintf("请求参数错误: %s!\n", err.Error())})
		return
	}
	icon, err := c.FormFile("icon_path")
	if err != nil {
		c.JSON(http.StatusOK, gin.H{
			"code": 400,
			"msg":  "图片上传失败",
		})
	}
	if err = i.CheckUploads(path.Ext(strings.ToLower(icon.Filename))); err != nil {
		log.Println(err.Error())
		i.Logger.Errorf("%s!\n", err.Error())
		c.JSON(http.StatusOK, gin.H{"code": 400, "msg": fmt.Sprintf("%s!\n", err.Error())})
		return
	}
	if err = i.SaveIcon(icon, c); err != nil {
		i.Logger.Errorf("%s!\n", err.Error())
		c.JSON(http.StatusOK, gin.H{"code": 400, "msg": fmt.Sprintf("%s!\n", err.Error())})
		return
	}
	icon_attack, err := c.FormFile("icon_attack_path")
	if err != nil {
		c.JSON(http.StatusOK, gin.H{
			"code": 400,
			"msg":  "攻击图片上传失败",
		})
	}
	if err = i.CheckUploads(path.Ext(strings.ToLower(icon_attack.Filename))); err != nil {
		i.Logger.Errorf("%s!\n", err.Error())
		c.JSON(http.StatusOK, gin.H{"code": 400, "msg": fmt.Sprintf("%s!\n", err.Error())})
		return
	}
	if err = i.SaveIconAttack(icon_attack, c); err != nil {
		i.Logger.Errorf("%s!\n", err.Error())
		c.JSON(http.StatusOK, gin.H{"code": 400, "msg": fmt.Sprintf("%s!\n", err.Error())})
		return
	}
	if err = s.Inset(&req, i.IconPath, i.IconAttackPath); err != nil {
		i.Logger.Errorf("组件插入错误：%s\n", err.Error())
		c.JSON(http.StatusOK, gin.H{"code": 400, "msg": fmt.Sprintf("组件插入错误：%s\n", err.Error())})
		return
	}
	i.Logger.Info("组件插入成功")
	c.JSON(http.StatusOK, gin.H{"code": 200, "msg": "组件插入成功"})
	return
}

func (i Icon) Update(c *gin.Context) {
	req := dto.IconUpdateRequests{}
	s := service.Icon{}
	err := i.MakeContext(c).MakePostgres().Bind(&req, binding.JSON).MakeService(&s.Service).Errors
	if err != nil {
		i.Logger.Errorf("请求参数错误: %s!\n", err.Error())
		c.JSON(http.StatusOK, gin.H{"code": 400, "msg": fmt.Sprintf("请求参数错误: %s!\n", err.Error())})
		return
	}
	icon, err := c.FormFile("icon_path")
	if err != nil {
		c.JSON(http.StatusOK, gin.H{
			"code": 400,
			"msg":  "图片上传失败",
		})
	}
	if err = i.CheckUploads(strings.ToLower(icon.Filename)); err != nil {
		i.Logger.Errorf("%s!\n", err.Error())
		c.JSON(http.StatusOK, gin.H{"code": 400, "msg": fmt.Sprintf("%s!\n", err.Error())})
		return
	}
	if err = i.SaveIcon(icon, c); err != nil {
		i.Logger.Errorf("%s!\n", err.Error())
		c.JSON(http.StatusOK, gin.H{"code": 400, "msg": fmt.Sprintf("%s!\n", err.Error())})
		return
	}
	icon_attack, err := c.FormFile("icon_attack_path")
	if err != nil {
		c.JSON(http.StatusOK, gin.H{
			"code": 400,
			"msg":  "攻击图片上传失败",
		})
	}
	if err = i.CheckUploads(strings.ToLower(icon_attack.Filename)); err != nil {
		i.Logger.Errorf("%s!\n", err.Error())
		c.JSON(http.StatusOK, gin.H{"code": 400, "msg": fmt.Sprintf("%s!\n", err.Error())})
		return
	}
	if err = i.SaveIconAttack(icon_attack, c); err != nil {
		i.Logger.Errorf("%s!\n", err.Error())
		c.JSON(http.StatusOK, gin.H{"code": 400, "msg": fmt.Sprintf("%s!\n", err.Error())})
		return
	}
	if err = s.Update(&req, i.IconPath, i.IconAttackPath); err != nil {
		i.Logger.Errorf("组件更新错误：%s\n", err.Error())
		c.JSON(http.StatusOK, gin.H{"code": 400, "msg": fmt.Sprintf("组件更新错误：%s\n", err.Error())})
		return
	}
	i.Logger.Info("组件更新成功")
	c.JSON(http.StatusOK, gin.H{"code": 200, "msg": "组件更新成功"})
	return
}

func (i Icon) Status(c *gin.Context) {
	req := dto.IconStatusRequests{}
	s := service.Icon{}
	err := i.MakeContext(c).MakePostgres().Bind(&req, binding.JSON).MakeService(&s.Service).Errors
	if err != nil {
		i.Logger.Errorf("请求参数错误: %s!\n", err.Error())
		c.JSON(http.StatusOK, gin.H{"code": 400, "msg": fmt.Sprintf("请求参数错误: %s!\n", err.Error())})
		return
	}
	if err = s.Status(&req); err != nil {
		i.Logger.Errorf("组件状态修改错误：%s\n", err.Error())
		c.JSON(http.StatusOK, gin.H{"code": 400, "msg": fmt.Sprintf("组件状态修改错误：%s\n", err.Error())})
		return
	}
	i.Logger.Info("组件状态修改成功")
	c.JSON(http.StatusOK, gin.H{"code": 200, "msg": "组件状态修改成功"})
	return
}

func (i *Icon) SaveIcon(icon *multipart.FileHeader, c *gin.Context) error {
	uploadDir := images_dir
	if _, err := os.Stat(uploadDir); os.IsNotExist(err) {
		os.Mkdir(uploadDir, 0755)
	}
	ext := filepath.Ext(icon.Filename)
	newFileName := time.Now().Format("20060102150405") + "_" + strings.Split(icon.Filename, ".")[0] + ext
	filePath := filepath.Join(uploadDir, newFileName)
	if err := c.SaveUploadedFile(icon, filePath); err != nil {
		return err
	}
	i.IconPath = newFileName
	return nil
}

func (i *Icon) SaveIconAttack(icon *multipart.FileHeader, c *gin.Context) error {
	uploadDir := images_dir
	if _, err := os.Stat(uploadDir); os.IsNotExist(err) {
		os.Mkdir(uploadDir, 0755)
	}
	ext := filepath.Ext(icon.Filename)
	newFileName := time.Now().Format("20060102150405") + "_" + strings.Split(icon.Filename, ".")[0] + ext
	filePath := filepath.Join(uploadDir, newFileName)
	if err := c.SaveUploadedFile(icon, filePath); err != nil {
		return err
	}
	i.IconAttackPath = newFileName
	return nil
}

func (i *Icon) CheckUploads(suffix string) error {
	switch suffix {
	case ".png":
		return nil
	case ".jpg":
		return nil
	case ".svg":
		return nil
	}
	return fmt.Errorf("图片文件格式报错")
}
